#!/usr/bin/env python3
import sys
from scapy.all import *
from scapy.fields import *

class SourceRoute(Packet):
    fields_desc = [
        BitField("bos", 0, 1),
        BitField("port", 0, 15)
    ]

bind_layers(Ether, SourceRoute, type=0x1234)
bind_layers(SourceRoute, SourceRoute, bos=0)
bind_layers(SourceRoute, IP, bos=1)
bind_layers(SourceRoute, IPv6, bos=1)

def get_if():
    ifs = get_if_list()
    iface = next((i for i in ifs if "eth0" in i), None)
    if not iface:
        print("Cannot find eth0 interface")
        exit(1)
    return iface

def handle_pkt(pkt):
    if Ether in pkt:
        if pkt[Ether].type == 0x1234 and SourceRoute in pkt:
            print("\n=== Received Source Routed Packet ===")
            # 提取源路由路径
            route = []
            sr_layer = pkt[Ether].payload
            while isinstance(sr_layer, SourceRoute):
                route.append(str(sr_layer.port))
                sr_layer = sr_layer.payload
            
            print(f"Route Path: {' -> '.join(route)}")
            
            if IPv6 in pkt:
                print(f"IPv6 Packet: {pkt[IPv6].src} -> {pkt[IPv6].dst}")
            elif IP in pkt:
                print(f"IPv4 Packet: {pkt[IP].src} -> {pkt[IP].dst}")
        
        elif IPv6 in pkt:
            print(f"\n=== Received IPv6 Packet: {pkt[IPv6].src} -> {pkt[IPv6].dst} ===")
        elif IP in pkt:
            print(f"\n=== Received IPv4 Packet: {pkt[IP].src} -> {pkt[IP].dst} ===")
        
        pkt.show2()
    sys.stdout.flush()

def main():
    iface = get_if()
    print(f"Sniffing on interface {iface}")
    
    # 捕获所有UDP 4321端口的包和源路由包
    sniff_filter = "(udp and port 4321) or (ether proto 0x1234)"
    sniff(iface=iface, filter=sniff_filter, prn=handle_pkt)

if __name__ == '__main__':
    main()